#include "ktag.h"
#include "themeController.h"
#include "ktoolbutton.h"
#include <QPainter>
#include <QFontMetrics>
#include <QApplication>
#include <QToolButton>
#include <QStyleOption>
#include <QDebug>
#include <QPalette>
#include "parmscontroller.h"
#include "accessinfohelper.h"

namespace kdk {
class KTagPrivate:public QObject,public ThemeController
{
    Q_OBJECT
    Q_DECLARE_PUBLIC(KTag)

public:
    KTagPrivate(KTag*parent);
    void changeTheme();
    void updateDeleteBtnColor(QPalette palette);

private:
    KTag* q_ptr;
    QString m_text;
    KToolButton* m_pDeleteBtn;
    TagStyle m_style;
    QColor m_backgroundColor;
    bool m_isClosable;
    bool m_isBackgroundFlag;
    bool m_isTranslucent;
};

KTag::KTag(QWidget *parent)
    :QPushButton(parent)
    ,d_ptr(new KTagPrivate(this))
{
    Q_D(KTag);
    setClosable(false);
    d->changeTheme();
    connect(Parmscontroller::self(),&Parmscontroller::modeChanged,this,[=](bool flag){
        updateGeometry();
    });
    connect(d->m_gsetting,&QGSettings::changed,this,[=](){
        d->changeTheme();
        d->updateDeleteBtnColor(palette());
    });
}

void KTag::setClosable(bool flag)
{
    Q_D(KTag);
    d->m_isClosable = flag;
    if(flag)
        setMinimumWidth(88);
    d->updateDeleteBtnColor(palette());
    update();
}

bool KTag::closable()
{
    Q_D(KTag);
    return d->m_isClosable;
}

void KTag::setText(const QString &text)
{
    Q_D(KTag);
    d->m_text = text;
    update();
}

void KTag::setTagStyle(TagStyle style)
{
    Q_D(KTag);
    d->m_style = style;
    d->changeTheme();
    update();
}

TagStyle KTag::tagStyle()
{
    Q_D(KTag);
    d->updateDeleteBtnColor(palette());
    return d->m_style;
}

void KTag::setBackgroundColor(QColor color)
{
    Q_D(KTag);
    d->m_isBackgroundFlag = true;
    d->m_backgroundColor = color;
    d->updateDeleteBtnColor(palette());
}

void KTag::setTranslucent(bool flag)
{
    Q_D(KTag);
    d->m_isTranslucent = flag;
    if(flag)
        d->updateDeleteBtnColor(palette());
}

bool KTag::translucent()
{
    Q_D(KTag);
    return d->m_isTranslucent;
}

QString KTag::text()
{
    Q_D(KTag);
    return d->m_text;
}

void KTag::paintEvent(QPaintEvent *event)
{
    Q_D(KTag);
    QStyleOptionButton option;
    initStyleOption(&option);
    QColor bkgColor;
    QColor highColor = palette().highlight().color();
    QColor iconColor;
    QColor fontColor;
    QRect iconRect;
    QRect textRect;
    if(!option.state.testFlag(QStyle::State_Enabled))
    {
        bkgColor = palette().color(QPalette::Disabled,QPalette::Button);
        iconColor = palette().color(QPalette::Disabled,QPalette::HighlightedText);
        fontColor = palette().color(QPalette::Disabled,QPalette::HighlightedText);
    }
    else
    {
        if(d->m_isTranslucent || d->m_isBackgroundFlag)
        {
            iconColor = palette().highlight().color();
            fontColor = palette().highlight().color();
        }
        else
        {
            iconColor = Qt::white;
            fontColor = Qt::white;
        }

        if(!d->m_isBackgroundFlag)
        {
            bkgColor = highColor;
            if(option.state.testFlag(QStyle::State_MouseOver))
            {
                if(option.state.testFlag(QStyle::State_Sunken))
                {
                    if(d->m_isTranslucent)
                        bkgColor.setAlphaF(0.45);
                    else
                        bkgColor = ThemeController::mixColor(bkgColor,option.palette.brightText().color(),0.2);
                }
                else
                {
                    if(d->m_isTranslucent)
                        bkgColor.setAlphaF(0.3);
                    else
                        bkgColor = ThemeController::mixColor(bkgColor,option.palette.brightText().color(),0.05);
                }
            }
            else
            {
                if(d->m_isTranslucent)
                    bkgColor.setAlphaF(0.15);
            }
        }
        else
        {
            bkgColor = d->m_backgroundColor;
        }
    }

    if(closable())
    {
        QRect rect = option.rect.adjusted(8,0,-(d->m_pDeleteBtn->width()),0);
        int drawLength = drawLength = option.iconSize.width() + 4 + fontMetrics().width((d->m_text));;

        if(!option.icon.pixmap(option.iconSize).isNull() && d->m_style==IconTag)
        {
            if(rect.width() > drawLength )
            {
                iconRect = QRect(rect.center().x() - drawLength/2,
                                 rect.center().y() - option.iconSize.height()/2,
                                 option.iconSize.width(),
                                 option.iconSize.height());
                textRect = QRect(iconRect.right() + 4,
                                 rect.center().y() - fontMetrics().height()/2,
                                 fontMetrics().width(d->m_text),
                                 fontMetrics().height());
            }
            else
            {
                iconRect = QRect(rect.x(),
                                 rect.center().y() - option.iconSize.height()/2,
                                 option.iconSize.width(),
                                 option.iconSize.height());
                textRect = QRect(iconRect.right() + 4,
                                 rect.center().y() - fontMetrics().height()/2,
                                 rect.width() - iconRect.width(),
                                 fontMetrics().height());
            }
        }
        else
        {
            if(rect.width() > drawLength )
            {
                textRect = QRect(( option.rect.width() - fontMetrics().width(d->m_text))/2,
                                 rect.center().y() - fontMetrics().height()/2,
                                 fontMetrics().width(d->m_text),
                                 fontMetrics().height());
            }
            else
            {
                textRect = QRect(4,
                                 rect.center().y() - fontMetrics().height()/2,
                                 option.rect.width() - d->m_pDeleteBtn->width() ,
                                 fontMetrics().height());
            }
        }
    }
    else
    {
        QRect rect = option.rect.adjusted(8,0,0,0);
        int drawLength;

        if(!option.icon.pixmap(option.iconSize).isNull() && d->m_style==IconTag)
        {
            drawLength = option.iconSize.width() + 4 + fontMetrics().width((d->m_text));
            if(rect.width() > drawLength )
            {
                iconRect = QRect(rect.center().x() - drawLength/2,
                                 rect.center().y() - option.iconSize.height()/2,
                                 option.iconSize.width(),
                                 option.iconSize.height());
                textRect = QRect(iconRect.right() + 4,
                                 rect.center().y() - fontMetrics().height()/2,
                                 fontMetrics().width(d->m_text),
                                 fontMetrics().height());
            }
            else
            {
                iconRect = QRect(rect.x(),
                                 rect.center().y() - option.iconSize.height()/2,
                                 option.iconSize.width(),
                                 option.iconSize.height());
                textRect = QRect(iconRect.right() + 4,
                                 rect.center().y() - fontMetrics().height()/2,
                                 rect.width() - 4 - iconRect.width(),
                                 fontMetrics().height());
            }
        }
        else
        {
            drawLength =  fontMetrics().width((d->m_text));
            if(rect.width() > drawLength )
            {
                textRect = QRect(( option.rect.width() - fontMetrics().width(d->m_text))/2,
                                 rect.center().y() - fontMetrics().height()/2,
                                 fontMetrics().width(d->m_text),
                                 fontMetrics().height());
            }
            else
            {
                textRect = QRect(4,
                                 rect.center().y() - fontMetrics().height()/2,
                                 rect.width() - 4,
                                 fontMetrics().height());
            }
        }
    }
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    QRect rect = this->rect();
    if(d->m_isClosable)
    {
        d->m_pDeleteBtn->show();
        d->m_pDeleteBtn->move(width()-d->m_pDeleteBtn->width(),(height()-d->m_pDeleteBtn->height())/2);
        rect.adjust(0,0,-16,0);
    }
    else
    {
        d->m_pDeleteBtn->hide();
    }
    QColor color = palette().color(QPalette::Highlight);
    switch (d->m_style)
    {
    case HighlightTag:
        painter.setBrush(color);
        painter.setPen(Qt::PenStyle::NoPen);
        painter.drawRoundedRect(this->rect().adjusted(1,1,-1,-1),6,6);
        painter.setPen(QColor("#FFFFFF"));
        if(fontMetrics().width(d->m_text) > textRect.width())
        {
            QString str= fontMetrics().elidedText(d->m_text,Qt::ElideRight,textRect.width());
            painter.drawText(textRect,Qt::AlignCenter,str);
            setToolTip(d->m_text);
        }
        else
        {
            setToolTip("");
            painter.drawText(textRect,Qt::AlignCenter,d->m_text);
        }
        break;
    case BoderTag:
        painter.setBrush(QColor(Qt::transparent));
        painter.setPen(color);
        painter.drawRoundedRect(this->rect().adjusted(1,1,-1,-1),6,6);
        if(fontMetrics().width(d->m_text) > textRect.width())
        {
            QString str= fontMetrics().elidedText(d->m_text,Qt::ElideRight,textRect.width());
            painter.drawText(textRect,Qt::AlignCenter,str);
            setToolTip(d->m_text);
        }
        else
        {
            setToolTip("");
            painter.drawText(textRect,Qt::AlignCenter,d->m_text);
        }
        break;
    case BaseBoderTag:
        {
            QColor backColor=color;
            backColor.setAlpha(38);
            painter.setBrush(backColor);
            painter.setPen(color);
            painter.drawRoundedRect(this->rect().adjusted(1,1,-1,-1),6,6);
            if(fontMetrics().width(d->m_text) > textRect.width())
            {
                QString str= fontMetrics().elidedText(d->m_text,Qt::ElideRight,textRect.width());
                painter.drawText(textRect,Qt::AlignCenter,str);
                setToolTip(d->m_text);
            }
            else
            {
                setToolTip("");
                painter.drawText(textRect,Qt::AlignCenter,d->m_text);
            }
            break;
        }
    case GrayTag:
        painter.setBrush(this->palette().color(QPalette::Disabled,QPalette::Highlight));
        painter.setPen(Qt::PenStyle::NoPen);
        painter.drawRoundedRect(this->rect().adjusted(1,1,-1,-1),6,6);
        painter.setPen(this->palette().color(QPalette::Text));
        if(fontMetrics().width(d->m_text) > textRect.width())
        {
            QString str= fontMetrics().elidedText(d->m_text,Qt::ElideRight,textRect.width());
            painter.drawText(textRect,Qt::AlignCenter,str);
            setToolTip(d->m_text);
        }
        else
        {
            setToolTip("");
            painter.drawText(textRect,Qt::AlignCenter,d->m_text);
        }
        break;
    case IconTag:
    {
        QPixmap pixmap = option.icon.pixmap(option.iconSize);
        painter.setPen(Qt::NoPen);
        painter.setBrush(bkgColor);
        painter.drawRoundedRect(this->rect().adjusted(1,1,-1,-1),6,6);
        painter.drawPixmap(iconRect,ThemeController::drawColoredPixmap(pixmap,iconColor));
        painter.setPen(fontColor);
        if(fontMetrics().width(d->m_text) > textRect.width())
        {
            QString str= fontMetrics().elidedText(d->m_text,Qt::ElideRight,textRect.width());
            painter.drawText(textRect,Qt::AlignCenter,str);
            setToolTip(d->m_text);
        }
        else
        {
            setToolTip("");
            painter.drawText(textRect,Qt::AlignCenter,d->m_text);
        }
        break;
    }
    default:
        break;

    }
}

QSize KTag::sizeHint() const
{
    auto size= QPushButton::sizeHint();
    size.setHeight(Parmscontroller::parm(Parmscontroller::Parm::PM_TagHeight));
    return size;
}

KTagPrivate::KTagPrivate(KTag *parent)
    :q_ptr(parent),
      m_isClosable(false),
      m_text(""),
      m_style(HighlightTag),
      m_isBackgroundFlag(false),
      m_isTranslucent(false)
{
    Q_Q(KTag);
    m_pDeleteBtn = new KToolButton(q);
    m_pDeleteBtn->setIconSize(QSize(16,16));
    m_pDeleteBtn->setFixedSize(32,32);
    connect(m_pDeleteBtn,&KToolButton::clicked,q,&KTag::close);
    m_pDeleteBtn->hide();
    QPalette btnPalette;
    btnPalette.setBrush(QPalette::Active, QPalette::Button, Qt::transparent);
    btnPalette.setBrush(QPalette::Inactive, QPalette::Button, Qt::transparent);
    btnPalette.setBrush(QPalette::Disabled, QPalette::Button, Qt::transparent);

    btnPalette.setBrush(QPalette::Active, QPalette::Highlight, Qt::transparent);
    btnPalette.setBrush(QPalette::Inactive, QPalette::Highlight, Qt::transparent);
    btnPalette.setBrush(QPalette::Disabled, QPalette::Highlight, Qt::transparent);
    m_pDeleteBtn->setAutoFillBackground(true);
    m_pDeleteBtn->setPalette(btnPalette);
    m_pDeleteBtn->setFocusPolicy(Qt::NoFocus);
    m_pDeleteBtn->setCursor(Qt::ArrowCursor);

    KDK_ALL_INFO_FORMAT(m_pDeleteBtn,"");
}

void KTagPrivate::changeTheme()
{
    Q_Q(KTag);

    initThemeStyle();
//    updateDeleteBtnColor();
}

void KTagPrivate::updateDeleteBtnColor(QPalette palette)
{
    Q_Q(KTag);
    QIcon icon = QIcon::fromTheme("application-exit-symbolic");
    QSize size(m_pDeleteBtn->iconSize());
    switch (m_style)
    {
    case HighlightTag:
        m_pDeleteBtn->setIcon(drawColoredPixmap(icon.pixmap(size),QColor("#FFFFFF")));
        break;
    case BoderTag:
        m_pDeleteBtn->setIcon(drawColoredPixmap(icon.pixmap(size),palette.color(QPalette::Text)));
        break;
    case BaseBoderTag:
        m_pDeleteBtn->setIcon(drawColoredPixmap(icon.pixmap(size),palette.color(QPalette::Text)));
        break;
    case GrayTag:
        m_pDeleteBtn->setIcon(drawColoredPixmap(icon.pixmap(size),palette.color(QPalette::Text)));
        break;
    case IconTag:
        if(m_isTranslucent || m_isBackgroundFlag)
            m_pDeleteBtn->setIconColor(true,palette.highlight().color());//m_backgroundColor
        else
            m_pDeleteBtn->setIconColor(true,Qt::white);
        break;
    default:
        break;
    }
}
}

#include "ktag.moc"
#include "moc_ktag.cpp"
